package co.edu.unal.franquicias.mastercard.auth;

import javax.ws.rs.PathParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;

/**
 * Base class implementing common logic for all application resources (checking
 * for user name and roles)
 */
public abstract class ResourceBase {
    protected @PathParam("user") String user;
    protected @Context SecurityContext security;
    protected @Context UriInfo uriInfo;

    // for resources not under the /{user} path and those which are not
    // subresources of UserResource
    protected ResourceBase() {
    	
    	System.out.println("Doing something");
    }

    // for resources with user initialized
    ResourceBase(ResourceBase parent) {
        this(parent.user, parent);
    }

    // for UserResource, which can't rely on getting the user name from
    // the parent
    ResourceBase(String user, ResourceBase parent) {
        this.user = user;
        this.security = parent.security;
        this.uriInfo = parent.uriInfo;
    }

    /**
     * Checks if the user is authenticated and authorized to access a given resource.
     *
     * @throws RequestProcessingException thrown if user is not authenticated or authorized to access the resource
     */
    public void checkUser() throws RequestProcessingException {
    	
    	System.out.println("Checking user ...");
    	
        // if the user is not authorized, throw "UNAUTHORIZED" exception
        if ((security == null) || (security.getUserPrincipal() == null)) {
            throw new RequestProcessingException(Response.Status.UNAUTHORIZED, uriInfo);
        }
        // if the user is authenticated, but is trying to access resources they are not
        // authorized to access, throw "FORBIDDEN" exception
        if ((user != null) && !user.equals(security.getUserPrincipal().getName())) {
            throw new RequestProcessingException(Response.Status.FORBIDDEN, uriInfo);
        }
    }

    /**
     * Checks if the user is in the role allowing write access. Throws exception if not.
     *
     * @throws RequestProcessingException thrown if the user is not in the role allowing write access
     */
    public void checkWrite() throws RequestProcessingException {
        if ((security == null) || !security.isUserInRole("user")) {
            throw new RequestProcessingException(Response.Status.FORBIDDEN, uriInfo);
        }
    }
}
